from apscheduler.schedulers.background import BackgroundScheduler, BlockingScheduler
from apscheduler.jobstores.redis import RedisJobStore
from apscheduler.executors.pool import ThreadPoolExecutor

from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.triggers.cron import CronTrigger
from apscheduler.jobstores.base import JobLookupError


class SchedulerJob:
    def __init__(self, **kwargs):
        self.scheduler = None

        if kwargs:
            self.init_config(**kwargs)

    def init_config(self, store_configure, default_configure, pool_count=20, is_background=True):
        jobstores = {'default': RedisJobStore(**store_configure)}
        executors = {'default': ThreadPoolExecutor(pool_count)}
        if is_background:
            self.scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors,
                                                 job_defaults=default_configure)
            return
        self.scheduler = BlockingScheduler(jobstores=jobstores, executors=executors, job_defaults=default_configure)
    
    def add_job(self, job_id, func, cron, kwargs=None):
        if not cron:  # 不定时执行
            self.delete_job(job_id)
            return
        
        trigger = IntervalTrigger(**{cron['unit']: cron['interval']}) if cron.get('interval') is not None else CronTrigger(**cron)
        self.scheduler.add_job(func=func, 
                               id=job_id,
                               name=job_id,
                               kwargs=kwargs, 
                               trigger=trigger, 
                               replace_existing=True)
      
    def delete_job(self, job_id):
        """清除task"""
        try:
            scheduler_job.scheduler.remove_job(job_id)
        except JobLookupError as e:  # 任务不存在的忽略
            pass
        except Exception as e:
            print(f'TODO... {e}')


scheduler_job = SchedulerJob()


if __name__ == '__main__':
    scheduler_job.init_config(
        default_configure={'coalesce': True, 'max_instances': 1},
        store_configure={'default': RedisJobStore(host='192.168.101.79', password='MY.io2019')}
    )
